package com.adee.design.structure.proxy.dynamicproxy.jdk;


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 动态代理，发生在运行时
// jdk动态代理问题：类必须实现接口
public class Test {
    public static void main(String[] args) {
        LawyerInvocationHandler zhangsanProxyLogic = new LawyerInvocationHandler(new Zhangsan()); // 代理逻辑
        Speaker zhangsanLawyer = (Speaker)Proxy.newProxyInstance(
                Test.class.getClassLoader(), new Class[]{Speaker.class}, zhangsanProxyLogic);
        zhangsanLawyer.speak();
        zhangsanLawyer.hello();
        LawyerInvocationHandler lisiProxyLogic = new LawyerInvocationHandler(new Lisi()); // 代理逻辑
        Speaker lisiLawyer = (Speaker)Proxy.newProxyInstance(
                Test.class.getClassLoader(), new Class[]{Speaker.class}, lisiProxyLogic);
        lisiLawyer.speak();
    }
}

class LawyerInvocationHandler implements InvocationHandler {
    private Object obj;
    public LawyerInvocationHandler(Object obj) {
        this.obj = obj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        } else {
            if("speak".equals(method.getName())) {
                System.out.println("引用法律条文");
                Object ret = method.invoke(obj, args);
                System.out.println("得出结论：打人是不对的");
                return ret;
            } else {
                return method.invoke(obj, args);
            }
        }
    }
}

interface Speaker {
    void speak();
    void hello();
}

class Zhangsan implements Speaker {
    @Override
    public void speak() {
        System.out.println("Zhangsan被老婆打了");
    }

    @Override
    public void hello() {
        System.out.println("hello Zhangsan");
    }
}

class Lisi implements Speaker {
    @Override
    public void speak() {
        System.out.println("Lisi被老婆打了");
    }

    @Override
    public void hello() {
        System.out.println("hello Lisi");
    }
}




